#pragma once

#include "Containers/String.h"
#include <memory>

class CType;

class IEditorScriptIdentifier
{
    
};

class CEditorScriptVariable :public IEditorScriptIdentifier
{
public:
    CString Name; 

    CType* NativeType=nullptr;

};


class CEditorScriptFunction : public IEditorScriptIdentifier
{
public:
    //function name
    CString Name; 

    TVector<std::weak_ptr<CEditorScriptVariable>> Variables;

    //find variable by name
    std::weak_ptr<CEditorScriptVariable> FindVariable(const CString& InName);
};

class CEditorScriptField : public IEditorScriptIdentifier
{
public:
    //field name
    CString Name; 


};

//class, struct, enum
class CEditorScriptClass : public IEditorScriptIdentifier
{
public:
    //class name
    CString Name; 

    //class fields
    TVector<std::weak_ptr<CEditorScriptField>> Fields;

    //class functions
    TVector<std::weak_ptr<CEditorScriptFunction>> Functions;

    //inner classes
    TVector<std::weak_ptr<CEditorScriptClass>> InnerClasses;

    //find inner class by name
    std::weak_ptr<CEditorScriptClass> FindClass(const CString& InName);

    //find field by name
    std::weak_ptr<CEditorScriptField> FindField(const CString& InName);

    //find function by name
    std::weak_ptr<CEditorScriptFunction> FindFunction(const CString& InName);
};


class CEditorScriptNamespace : public IEditorScriptIdentifier
{
public:
    //namespace name
    //can be empty if the namespace is global namespace
    CString Name; 

    //namespace classes
    TVector<std::weak_ptr<CEditorScriptClass>> Classes;

    //inner namespaces
    TVector<std::weak_ptr<CEditorScriptNamespace>> InnerNamespaces;

    //find inner namespace by name
    std::weak_ptr<CEditorScriptNamespace> FindNamespace(const CString& InName);

    //find class by name
    std::weak_ptr<CEditorScriptClass> FindClass(const CString& InName);

    
    //find class recursively
    std::weak_ptr<CEditorScriptClass> FindClassRecursively(const CString& InName);

};